#!/usr/bin/env python
import uuid

import openstack

from app import db
from app.models import rangeModel, userModel
from configs.get_config_info import env_config
from manage import app
from utils.crypto import decrypt_pw


def gen_id():
    return uuid.uuid1()


openstack_config = env_config["USER_TO_OPENSTACK"]
(
    hydropower_uuid,
    hydropower_mis_uuid,
    hydropower_attack_uuid,
    hydropower_wincc_uuid,
    hydropower_smz_uuid,
) = (gen_id(), gen_id(), gen_id(), gen_id(), gen_id())
smart_uuid, smart_mis_uuid, smart_wincc_uuid, smart_snd_uuid, smart_abd_uuid = (
    gen_id(),
    gen_id(),
    gen_id(),
    gen_id(),
    gen_id(),
)
(
    thermal_power_uuid,
    thermal_power_xmz_plc1_uuid,
    thermal_power_sisi_uuid,
    thermal_power_xmz_plc_uuid,
    thermal_power_wincc3_uuid,
    thermal_power_mis1_uuid,
    thermal_power_wincc_uuid,
    thermal_power_wincc1_uuid,
) = (gen_id(), gen_id(), gen_id(), gen_id(), gen_id(), gen_id(), gen_id(), gen_id())

thermal_power_args = {
    "name": "中药制粒场景",
    "describe": "中药制粒靶场模板",
    "difficulty": "2",
    "task_id": "2",
    "type": "1",
    "range_uuid": thermal_power_uuid,
    "vm_args": [
        {
            "image": "534f7ea2-cb9b-4b81-b1b1-0a3e8e7747ec",
            "range_uuid": thermal_power_uuid,
            "vm_uuid": thermal_power_xmz_plc1_uuid,
            "type": "plc-smz",
            "vm_name": "西门子PLC",
        },
        {
            "image": "afcf6a70-4eeb-4343-b9d6-fa1784811c21",
            "range_uuid": thermal_power_uuid,
            "vm_uuid": thermal_power_wincc3_uuid,
            "type": "wincc",
            "vm_name": "wincc",
        },
    ],
    "range_template_type": rangeModel.Range.RangeTemplate.chinese_medicine.name,
    "tp_json": '{"name": "中药制粒场景", "nodeList": [{"id": "pwndqljvm", "name": "wincc", "type": "wincc", "left": "254.813px",'
    '"top": "129.031px", "ico": "el-icon-circle-plus-outline", "state": "created", "vm_uuid": "%s"},'
    '{"id": "rcjonn6014", "name": "西门子PLC", "type": "plc-smz", "left": "334px", "top": "357px", "ico": "el-icon-circle-plus-outline",'
    '"state": "created", "vm_uuid": "%s"}, {"id": "dhpd6ltyxf", "name": "交换机", "type": "switch",'
    '"left": "314.813px", "top": "236.231px", "ico": "el-icon-circle-plus-outline", "state": ""}], "lineList": [{"from": "pwndqljvm",'
    '"to": "dhpd6ltyxf"}, {"from": "dhpd6ltyxf", "to": "rcjonn6014"}]}'
    % (thermal_power_wincc3_uuid, thermal_power_xmz_plc1_uuid),
    "tp_img": "",
}

# 火力发电
(
    huo_power_uuid,
    huo_power_xmz_plc1_uuid,
    huo_power_sisi_uuid,
    huo_power_xmz_plc_uuid,
    huo_power_wincc3_uuid,
    huo_power_mis1_uuid,
    huo_power_wincc_uuid,
    huo_power_wincc1_uuid,
) = (gen_id(), gen_id(), gen_id(), gen_id(), gen_id(), gen_id(), gen_id(), gen_id())

huo_power_args = {
    "name": "火力发电",
    "describe": "火力发电靶场模板",
    "difficulty": "2",
    "task_id": "2",
    "type": "1",
    "range_uuid": huo_power_uuid,
    "vm_args": [
        {
            "image": "267ee854-46cc-4ae8-be76-6302a8c5abba",
            "range_uuid": huo_power_uuid,
            "vm_uuid": huo_power_xmz_plc1_uuid,
            "type": "plc-smz",
            "vm_name": "火力发电场景-西门子PLC-燃烧系统",
        },
        {
            "image": "3a8b7d17-8b37-44c0-bcda-f04ef1a599c7",
            "range_uuid": huo_power_uuid,
            "vm_uuid": huo_power_sisi_uuid,
            "type": "Win7-SISI",
            "vm_name": "SISI数据库",
        },
        {
            "image": "0ab9d402-ec9a-4230-86bd-d787a6a2aa33",
            "range_uuid": huo_power_uuid,
            "vm_uuid": huo_power_xmz_plc_uuid,
            "type": "plc-smz",
            "vm_name": "火力发电场景-西门子PLC-汽水系统",
        },
        {
            "image": "c49b6986-e90b-4c98-8cc3-267576295ee5",
            "range_uuid": huo_power_uuid,
            "vm_uuid": huo_power_wincc3_uuid,
            "type": "wincc",
            "vm_name": "火力发电场景-wincc-汽水系统",
        },
        {
            "image": "513e5ee6-407e-4aa9-9767-1564324f9222",
            "range_uuid": huo_power_uuid,
            "vm_uuid": huo_power_mis1_uuid,
            "type": "mis",
            "vm_name": "mis系统",
        },
        {
            "image": "f57add06-78b1-4bfb-a7e4-37364cb16cc6",
            "range_uuid": huo_power_uuid,
            "vm_uuid": huo_power_wincc_uuid,
            "type": "wincc",
            "vm_name": "火力发电场景-wincc主控",
        },
        {
            "image": "91cbe5c4-a3c8-4916-bd67-7e13c74a0b4e",
            "range_uuid": huo_power_uuid,
            "vm_uuid": huo_power_wincc1_uuid,
            "type": "wincc",
            "vm_name": "火力发电场景-wincc-燃烧系统",
        },
    ],
    "range_template_type": rangeModel.Range.RangeTemplate.thermal_power.name,
    "tp_json": '{"name":"火力发电【勿删】","nodeList":[{"id":"qkcvasmq38","name":"交换机","type":"switch","left":"406px","top":"145px","ico":"el-icon-circle-plus-outline","state":""},{"id":"r7p0k9ph3g","name":"交换机F1","type":"switch","left":"415px","top":"18px","ico":"el-icon-circle-plus-outline","state":""},{"id":"3b7q0bjvcl","name":"交换机2","type":"switch","left":"422px","top":"292px","ico":"el-icon-circle-plus-outline","state":""},{"id":"thtb1zx4ys","name":"火力发电场景-西门子PLC-汽水系统","type":"plc-smz","left":"733px","top":"510px","ico":"el-icon-circle-plus-outline","state":"created","vm_uuid":"%s"},{"id":"73u4czr42s","name":"工业防火墙","type":"industrialFirewall","left":"330px","top":"427px","ico":"el-icon-circle-plus-outline","state":""},{"id":"pj3cajkljq","name":"工业防火墙1","type":"industrialFirewall","left":"534px","top":"432px","ico":"el-icon-circle-plus-outline","state":""},{"id":"bfff4d0c-1698-45f7-9b5d-60b6f10411a1","name":"SISI数据库","type":"vm","left":"244px","top":"107px","ico":"el-icon-circle-plus-outline","state":"created","vm_uuid":"%s"},{"id":"qk4vbrt0pj","name":"火力发电场景-西门子PLC-燃烧系统","type":"plc-smz","left":"143px","top":"497px","ico":"el-icon-circle-plus-outline","state":"created","vm_uuid":"%s"},{"id":"tf2gzowcuc","name":"火力发电场景-wincc-汽水系统","type":"wincc","left":"615px","top":"250px","ico":"el-icon-circle-plus-outline","state":"created","vm_uuid":"%s"},{"id":"istoi1vbhc","name":"mis系统","type":"mis","left":"37px","top":"28px","ico":"el-icon-circle-plus-outline","state":"created","vm_uuid":"%s"},{"id":"1u7t45umf","name":"火力发电场景-wincc主控","type":"wincc","left":"581px","top":"154px","ico":"el-icon-circle-plus-outline","state":"created","vm_uuid":"%s"},{"id":"ehxgs4naj8","name":"火力发电场景-wincc-燃烧系统","type":"wincc","left":"189px","top":"299px","ico":"el-icon-circle-plus-outline","state":"created","vm_uuid":"%s"}],"lineList":[{"from":"r7p0k9ph3g","to":"qkcvasmq38"},{"from":"3b7q0bjvcl","to":"73u4czr42s"},{"from":"3b7q0bjvcl","to":"pj3cajkljq"},{"from":"pj3cajkljq","to":"thtb1zx4ys"},{"from":"qkcvasmq38","to":"3b7q0bjvcl"},{"from":"3b7q0bjvcl","to":"h74pm5uwrl"},{"from":"qk4vbrt0pj","to":"73u4czr42s"},{"from":"qkcvasmq38","to":"bfff4d0c-1698-45f7-9b5d-60b6f10411a1"},{"from":"tf2gzowcuc","to":"3b7q0bjvcl"},{"from":"1u7t45umf","to":"qkcvasmq38"},{"from":"ehxgs4naj8","to":"3b7q0bjvcl"},{"from":"istoi1vbhc","to":"r7p0k9ph3g"}]}'
    % (
        huo_power_xmz_plc_uuid,
        huo_power_sisi_uuid,
        huo_power_xmz_plc1_uuid,
        huo_power_wincc3_uuid,
        huo_power_mis1_uuid,
        huo_power_wincc_uuid,
        huo_power_wincc1_uuid,
    ),
    "tp_img": "",
}


hydropower_args = {
    "name": "风力发电场景2.0",
    "describe": "风力发电靶场模板",
    "difficulty": "2",
    "task_id": "2",
    "type": "1",
    "range_uuid": hydropower_uuid,
    "vm_args": [
        {
            "image": "d8f1e499-7740-4ad6-9384-262a1dbd03e6",
            "range_uuid": hydropower_uuid,
            "vm_uuid": hydropower_wincc_uuid,
            "type": "wincc",
            "vm_name": "wincc",
        },
        {
            "image": "8690c1e3-3f33-4e38-a038-4c6ca3ec593f",
            "range_uuid": hydropower_uuid,
            "vm_uuid": hydropower_smz_uuid,
            "type": "plc-smz",
            "vm_name": "西门子PLC",
        },
    ],
    "range_template_type": rangeModel.Range.RangeTemplate.wind_power_2.name,
    "tp_json": '{"name":"风电场景20211118","nodeList":[{"id":"kfmmn3h0bj","name":"wincc","type":"wincc","left":"178px","top":"90.4px",'
    '"ico":"el-icon-circle-plus-outline","state":"created","vm_uuid":"%s"},'
    '{"id":"twfxq3mnqy","name":"西门子PLC","type":"plc-smz","left":"324px","top":"351px","ico":"el-icon-circle-plus-outline",'
    '"state":"created","vm_uuid":"%s"},{"id":"z92ivzrd1i","name":"交换机","type":"switch",'
    '"left":"377px","top":"171px","ico":"el-icon-circle-plus-outline","state":""}],"lineList":[{"from":"kfmmn3h0bj","to":"z92ivzrd1i"},'
    '{"from":"z92ivzrd1i","to":"twfxq3mnqy"}]}'
    % (hydropower_wincc_uuid, hydropower_smz_uuid),
    "tp_img": "",
}

smart_args = {
    "name": "多品牌控制器组合场景",
    "describe": "多品牌控制器组合靶场模板",
    "difficulty": "2",
    "task_id": "2",
    "type": "1",
    "range_uuid": smart_uuid,
    "vm_args": [
        {
            "image": "4c86a815-6645-4398-9d60-ad2578b37ec1",
            "range_uuid": smart_uuid,
            "vm_uuid": smart_mis_uuid,
            "type": "wincc",
            "vm_name": "wincc",
        },
        {
            "image": "9668128f-6f86-4ea3-919c-ed3cb8be611a",
            "range_uuid": smart_uuid,
            "vm_uuid": smart_wincc_uuid,
            "type": "plc-xmz",
            "vm_name": "西门子plc",
        },
        {
            "image": "84e02ae0-3de6-467e-98fe-08900cd51290",
            "range_uuid": smart_uuid,
            "vm_uuid": smart_snd_uuid,
            "type": "plc-snd",
            "vm_name": "施耐德plc",
        },
        {
            "image": "90e60e71-b6bb-451a-987c-bb3283b85de9",
            "range_uuid": smart_uuid,
            "vm_uuid": smart_abd_uuid,
            "type": "plc-ab",
            "vm_name": "ab-plc",
        },
    ],
    "range_template_type": rangeModel.Range.RangeTemplate.multi_brand_controller_combinations.name,
    "tp_json": '{"name":"多品牌控制器组合场景","nodeList":[{"id":"dzdau2bzn","name":"wincc","type":"wincc","left":"370px","top":"108px",'
    '"ico":"el-icon-circle-plus-outline","state":"created","vm_uuid":"%s"},'
    '{"id":"xq3y7bd4h","name":"交换机","type":"switch","left":"375px","top":"221px","ico":"el-icon-circle-plus-outline","state":""},'
    '{"id":"fq2c6m8irp","name":"ab-plc","type":"plc-ab","left":"242px","top":"466px","ico":"el-icon-circle-plus-outline",'
    '"state":"created","vm_uuid":"%s"},{"id":"uokgqikpi","name":"施耐德plc","type":"plc-snd",'
    '"left":"383px","top":"430px","ico":"el-icon-circle-plus-outline","state":"created","vm_uuid":"%s"}'
    ',{"id":"rx3qsl4aaf","name":"西门子plc","type":"plc-smz","left":"606px","top":"394px","ico":"el-icon-circle-plus-outline",'
    '"state":"created","vm_uuid":"%s"}],"lineList":[{"from":"dzdau2bzn","to":"xq3y7bd4h"},'
    '{"from":"fq2c6m8irp","to":"xq3y7bd4h"},{"from":"uokgqikpi","to":"xq3y7bd4h"},{"from":"rx3qsl4aaf","to":"xq3y7bd4h"}]}'
    % (smart_mis_uuid, smart_abd_uuid, smart_snd_uuid, smart_wincc_uuid),
    "tp_img": "",
}


def add_range():
    global system_ranges
    for range in system_ranges:
        try:
            with app.app_context():
                # 创建靶场
                with db.auto_commit():
                    obj = rangeModel.Range(
                        name=range["name"],
                        type=range["type"],
                        difficulty=range["difficulty"],
                        describe=range["describe"],
                        user_id=1,
                        is_system=1,
                    )
                    rangeModel.db.session.add(obj)
                    rangeModel.db.session.commit()

                    # 插入关联表
                    rangeModel_obj = rangeModel.RangeLinkModule(
                        range_id=obj.id,
                        range_uuid=range["range_uuid"],
                        # type=range['type'],
                        user_id=1,
                    )
                    rangeModel.db.session.add(rangeModel_obj)
                    rangeModel.db.session.commit()

                    # 创建虚机
                    for vm_info in range["vm_args"]:
                        range_info = rangeModel.RangeLinkModule.query.filter_by(
                            range_uuid=vm_info["range_uuid"], user_id=1
                        ).first()
                        if not range_info:
                            print("range_info error")
                            break

                        # 保存拓扑图及各虚拟设备定位信息
                        rangeModel.Range.query.filter_by(id=range_info.range_id).update(
                            {
                                "topology_json": range["tp_json"],
                                "topology_img": range["tp_img"],
                            }
                        )

                        res = create_vm(vm_info)
                        if not res:
                            print("create {} error".format(vm_info["vm_name"]))

        except Exception as e:
            print(e)
    print("OK")


def create_vm(vm_info):
    project_id = userModel.User.query.filter_by(id=1).first().project_id
    flavor = openstack_config[project_id]["template_images_list"][vm_info["image"]][
        "flavor"
    ]
    ip = openstack_config[project_id]["template_images_list"][vm_info["image"]][
        "v4_fixed_ip"
    ]
    # 验证传入参数
    try:
        openstack_auth_config = decrypt_pw(env_config["OPENSTACK"]["auth"])
        conn = openstack.connect(
            auth=openstack_auth_config, auth_type=env_config["OPENSTACK"]["auth_type"]
        )
        openstack_image = conn.get_image(vm_info["image"])
        openstack_flavor = conn.get_flavor(flavor)
        if not all([openstack_image, openstack_flavor]):
            print("can't connect openstack image or flavor")
            return False

        with app.app_context():
            with db.auto_commit():
                obj = rangeModel.RangeVm(
                    vm_name=vm_info["vm_name"],
                    vm_uuid=vm_info["vm_uuid"],
                    range_uuid=vm_info["range_uuid"],
                    image=vm_info["image"],
                    flavor=flavor,
                    v4_fixed_ip=ip,
                    status=1,
                    user_id=1,
                )
                rangeModel.db.session.add(obj)
                rangeModel.db.session.commit()

    except Exception as e:
        print(e, "无法连接到云计算服务")
        return False
    return True


if __name__ == "__main__":
    system_ranges = (thermal_power_args,)
    add_range()
